home *** CD-ROM | disk | FTP | other *** search
- /* fsi.c
- * AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
- * LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
- *
- * filter: * 7
- * 3 5 1 (1/16)
- */
-
- #include "internal.h"
-
- #include <assert.h>
- #include <string.h> /* memset() */
- #include <stdlib.h> /* calloc() */
-
- #include "OS:hourglass.h"
- #include "OS:macros.h"
-
-
-
- /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- extern bool process_gif_16bpp_floyd_steinberg_66bit(
- const process_gif *p) {
- byte *rove;
- int width, height;
- int x, y;
- const os_colour *palette;
- int line_length;
- int *buffer, *this_row, *next_row;
- int buffer_width;
- int r, g, b;
- int or, og, ob;
- int t;
- int er, eg, eb;
- int eblr, eblg, eblb;
- int ebr, ebg, ebb;
-
- assert(p);
- assert(p->pixel_width > 0);
- assert(p->pixel_height > 0);
- assert(p->in_palette.colours);
-
- /*
- * floyd_steinberg requires storing error info for one pixel to right and one pixel to left
- * so we will just allocate an extra column for each row and not do any edge checks
- * each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
- */
- buffer_width = (p->pixel_width + 2) * 3;
- buffer = calloc(1, sizeof(*buffer) * (buffer_width * 2));
- if (!buffer) {
- /*
- * oh dear
- */
- return TRUE;
- }
-
- initialise_scaling_tables();
-
- /*
- * not we pre-load values from the process_gif array
- * because it considerably helps the compiler produce better code
- */
- rove = p->buffer;
- width = p->pixel_width;
- height = p->pixel_height;
- palette = p->in_palette.colours;
- line_length = p->line_length;
- for (y= height; (y > 0); y--) {
- if ((y & 7) == 0) {
- xhourglass_percentage((y * 100) / height);
- }
- this_row = buffer + (buffer_width * ((y + 2) % 2)) + 1*3; /* skip left hand 'dummy' column */
- next_row = buffer + (buffer_width * ((y + 1) % 2)); /* point inside left hand dummy column */
- memset(next_row, 0, sizeof(*next_row) * buffer_width);/* next row has no errors */
- er = eg = eb = 0; /* error along this row */
- /*
- * note that just because we are actually scanning/outputting right to left
- * doesn't matter as far as floyd_steinberg is concerned
- * although it might help if we could ``snake''
- */
- for (x= width - 1; (x >= 0); x--) {
- INPUT;
- r += *this_row++; /* add in errors from other row */
- r += er; /* add in errors from this row */
- g += *this_row++;
- g += eg;
- b += *this_row++;
- b += eb;
- PROCESS;
- r -= or; /* error */
- g -= og;
- b -= ob;
- er = (r * 7) / 16; /* diffuse pixel to `right' */
- eg = (g * 7) / 16;
- eb = (b * 7) / 16;
- eblr = (r * 3) / 16; /* diffuse pixel `below left' */
- eblg = (g * 3) / 16;
- eblb = (b * 3) / 16;
- *next_row += eblr; next_row++;
- *next_row += eblg; next_row++;
- *next_row += eblb; next_row++;
- ebr = (r * 5) / 16; /* diffuse pixel `below' */
- ebg = (g * 5) / 16;
- ebb = (b * 5) / 16;
- *next_row += ebr; next_row++;
- *next_row += ebg; next_row++;
- *next_row += ebb; next_row++;
- *next_row += r - (er + eblr + ebr); next_row++; /* diffuse pixel `below right' */
- *next_row += g - (eg + eblg + ebg); next_row++;
- *next_row += b - (eb + eblb + ebb); next_row++;
- next_row -= 3*2; /* adjust next_row pointer */
- }
- rove += line_length;
- }
- free(buffer);
- return FALSE;
- }
-
-
-
-